<template>
    <el-dialog
        model-value="menuDialogVisible"
        title="分配权限"
        width="30%"
        @close="handleClose"
    >
    <el-form
    ref="formRef"
    :model="form"
    label-width="100px"
    >
        <el-tree
        ref="treeRef"
        :data="treeData"
        :props="defaultProps"
        show-checkbox
        check-strictly
        :default-expand-all=true
        node-key="id"
        >
            <template #default="{ node, data }">
                <span class="custom-tree-node">
                    <span>{{ node.label }}</span>
                    <el-tag v-if="data.menu_type === 'F'" type="warning" size="small" style="margin-left: 8px">
                        按钮
                    </el-tag>
                </span>
            </template>
        </el-tree>
    </el-form>
    <template #footer>
        <span class="dialog-footer">
        <el-button type="primary" @click="handleConfirm">确认</el-button>
        <el-button @click="handleClose">取消</el-button>
        </span>
    </template>

    </el-dialog>
</template>

<script setup>
import {defineEmits, defineProps, ref, watch} from "vue";
import requestUtil, {getServerUrl} from "@/util/request";
import {ElMessage} from 'element-plus'

const defaultProps = {
    children: 'children',
    label: 'name'
}

const props = defineProps({
    id: {
        type: Number,
        default: -1,
        required: true
    },
    menuDialogVisible: {
        type: Boolean,
        default: false,
        required: true
        }
})

const form = ref({
    id: -1
})

const treeData = ref([]);
const formRef = ref(null)
const treeRef = ref(null)

const initFormData = async(id) => {
    try {
        // 获取全部的菜单树
        const res = await requestUtil.get("system/menu_tree")
        console.log("获取菜单树成功", res)
        treeData.value = res.menu_tree;
        form.value.id = id;
        
        // 获取角色对应的菜单id列表
        const res2 = await requestUtil.get("system/role_menu?role_id=" + id)
        
        // 使用 check-strictly 后，直接设置所有已勾选的节点即可
        console.log("角色已有的菜单ID:", res2.menuIdList)
        treeRef.value.setCheckedKeys(res2.menuIdList)

    } catch (err) {
        console.error("获取菜单树失败", err)
    }
}

// 获取节点的所有父节点ID
const getParentIds = (menuTree, nodeId) => {
    const parentIds = []
    
    // 递归查找节点并收集父节点ID
    const findParents = (nodes, targetId, parents = []) => {
        for (const node of nodes) {
            if (node.id === targetId) {
                parentIds.push(...parents)
                return true
            }
            if (node.children && node.children.length > 0) {
                if (findParents(node.children, targetId, [...parents, node.id])) {
                    return true
                }
            }
        }
        return false
    }
    
    findParents(menuTree, nodeId)
    return parentIds
}


watch(
() => props.menuDialogVisible,
() => {
    let id = props.id;
    console.log("id=" + id)
    if (id != -1) {
        initFormData(id)
    }
    }
)

const emits = defineEmits(['update:modelValue', 'initRoleList'])

const handleConfirm = () => {
    formRef.value.validate(async (valid) => {
    if (valid) {
      // 获取完全勾选的节点
      const checkedKeys = treeRef.value.getCheckedKeys()
      
      // 智能计算需要添加的父节点（实现半选效果）
      const parentIds = new Set()
      checkedKeys.forEach(nodeId => {
        const parents = getParentIds(treeData.value, nodeId)
        parents.forEach(pid => parentIds.add(pid))
      })
      
      // 合并勾选的节点和计算出的父节点
      const allKeys = [...new Set([...checkedKeys, ...parentIds])]
      
      console.log('完全勾选的节点:', checkedKeys)
      console.log('计算出的父节点:', Array.from(parentIds))
      console.log('提交的所有节点:', allKeys)
      
      await requestUtil.post("system/role/grant_menu/", {"role_id": form.value.id, "menuIds": allKeys})
      .then(res => {
        try {
          ElMessage.success("执行成功！")
          emits("initRoleList")
          handleClose();
        } catch (error) {
          ElMessage.error("执行失败！", error)
        }
      })
    } else {
      ElMessage.error("表单验证失败！")
    }
  })
}

const handleClose = () => {
emits('update:modelValue', false)
}
</script>
<style scoped>
.custom-tree-node {
    display: flex;
    align-items: center;
    flex: 1;
}
</style>